using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace MKDS_Course_Editor.KCL
{
    public partial class KclEditorControl : UserControl
    {
        private float scaleX;
        private float scaleY;
        private float maxwidth = 8192f * 2f;
        [Category("Display Settings")]
        public float MaxWidth
        {
            get { return maxwidth; }
            set { maxwidth = value; }
        }
        private float maxheight = 8192f * 2f;
        [Category("Display Settings")]
        public float MaxHeight
        {
            get { return maxheight; }
            set { maxheight = value; }
        }
        public KclPointCollection Vertex = new KclPointCollection();
        public KclPlanePointCollection Planes = new KclPlanePointCollection();
        public KclPointCollection Octree = new KclPointCollection();

        public bool vertex = true;
        public bool plane = true;
        public bool octree = true;
        public KclEditorControl()
        {
            InitializeComponent();
            t.IsBalloon = true;
            scaleX = (float)this.Width / MaxWidth;
            scaleY = (float)this.Height / MaxHeight;
            this.MouseWheel += new MouseEventHandler(NkmEditorControl_MouseWheel);
        }
        float scale = 1;
        void NkmEditorControl_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta < 0 && maxwidth < 8192f * 2f && maxheight < 8192f * 2f)
            {
                maxwidth *= 1.5f;
                maxheight *= 1.5f;
                scale /= 1.5f;
                hScrollBar1.Enabled = true;
                vScrollBar1.Enabled = true;
                //hScrollBar1.Value = (int)(0);
                hScrollBar1.Maximum = (int)(scale * 10);
                hScrollBar1.Minimum = (int)(-scale * 10);
                //vScrollBar1.Value = (int)(0);
                vScrollBar1.Maximum = (int)(scale * 10);
                vScrollBar1.Minimum = (int)(-scale * 10);
                scaleX = (float)this.Width / MaxWidth;
                scaleY = (float)this.Height / MaxHeight;
                pictureBox1.Invalidate();
                return;
            }
            else if (e.Delta > 0 && maxwidth != 0 && maxheight != 0)
            {
                maxwidth /= 1.5f;
                maxheight /= 1.5f;
                scale *= 1.5f;
                hScrollBar1.Enabled = true;
                vScrollBar1.Enabled = true;
                hScrollBar1.Maximum = (int)(scale * 10);
                hScrollBar1.Minimum = (int)(-scale * 10);
                //hScrollBar1.Value = (int)(0);
                vScrollBar1.Maximum = (int)(scale * 10);
                vScrollBar1.Minimum = (int)(-scale * 10);
                //vScrollBar1.Value = (int)(0);
                scaleX = (float)this.Width / MaxWidth;
                scaleY = (float)this.Height / MaxHeight;
                pictureBox1.Invalidate();
                return;
            }
            hScrollBar1.Enabled = false;
            vScrollBar1.Enabled = false;
        }

        private void NkmEditorControl_Load(object sender, EventArgs e)
        {

        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            //Rectangle ViewableBlocks = new Rectangle(hScrollBar.Value, vScrollBar.Value, ViewableWidth, ViewableHeight);
            // Rectangle ViewablePixels = new Rectangle(hScrollBar.Value * 16, vScrollBar.Value * 16, ViewableWidth * 16, ViewableHeight * 16);
            //Viewable.X += 4; Viewable.Y += 4; Viewable.Width -= 8; Viewable.Height -= 8;

            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
            e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;

            //e.Graphics.ScaleTransform(zoom, zoom);
            e.Graphics.TranslateTransform(-(8192f / ((float)scale / 2f) / 10f * hScrollBar1.Value),-( 8192f / ((float)scale / 2f) / 10f * vScrollBar1.Value));

            //if (bgImage != null)
            //    e.Graphics.DrawImage(bgImage, bgX, bgY);

            //RENDER PANNING BLOCKS GRID
            //for (int x = ViewableBlocks.X / 16; x <= (ViewableBlocks.Width + ViewableBlocks.X) / 16; x++)
            //   for (int y = ViewableBlocks.Y / 16; y <= (ViewableBlocks.Height + ViewableBlocks.Y) / 16; y++)
            //       e.Graphics.DrawRectangle(Pens.LightGray, x * 256, y * 256, 256, 256);


            //RENDER OBJECTS
            // for (int ObjIdx = 0; ObjIdx < Level.Objects.Count; ObjIdx++)
            // {
            //    Rectangle ObjRect = new Rectangle(Level.Objects[ObjIdx].X, Level.Objects[ObjIdx].Y, Level.Objects[ObjIdx].Width, Level.Objects[ObjIdx].Height);
            //    if (ObjRect.IntersectsWith(ViewableArea))
            //   {
            //        Level.Objects[ObjIdx].render(e.Graphics, this);
            //    }
            //}
            if (plane)
            {
                for (int i = 0; i < Planes.Length; i++)
                {
                    Planes[i].Render(e, scaleX, scaleY);
                }
            }
            int Nr = -1;
            if (vertex)
            {
                for (int i = 0; i < Vertex.Length; i++)
                {
                    Vertex[i].Render(e, scaleX, scaleY);
                }
            }
            if (octree)
            {
                for (int i = 0; i < Octree.Length; i++)
                {
                    Octree[i].Render(e, scaleX, scaleY);
                }
            }
            // foreach (NSMBSprite s in Level.Sprites)
            //   if (ViewablePixels.IntersectsWith(s.getRect()) || s.AlwaysDraw())
            //       s.render(e.Graphics, this);

            // foreach (NSMBView v in Level.Views)
            //     v.render(e.Graphics, this);
            // foreach (NSMBView v in Level.Zones)
            //     v.render(e.Graphics, this);

            //foreach (NSMBEntrance n in Level.Entrances)
            //     if (ViewablePixels.Contains(n.X, n.Y))
            //         n.render(e.Graphics, this);

            // foreach (NSMBPath p in Level.Paths)
            //     p.render(e.Graphics, this, false);
            // foreach (NSMBPath p in Level.ProgressPaths)
            //      p.render(e.Graphics, this, false);

            // if (mode != null)
            //     mode.RenderSelection(e.Graphics);

            // DS Screen preview
            //  if (showDSScreen)
            //  {
            //      e.Graphics.DrawRectangle(Pens.BlueViolet, dsScreenX, dsScreenY, 256, 192);
            //      e.Graphics.DrawLine(Pens.BlueViolet, dsScreenX + 128, dsScreenY, dsScreenX + 128, dsScreenY + 192);
            //      e.Graphics.DrawLine(Pens.BlueViolet, dsScreenX, dsScreenY + 96, dsScreenX + 256, dsScreenY + 96);
            //  }

            //  e.Graphics.TranslateTransform(hScrollBar.Value * 16, vScrollBar.Value * 16);
        }
        private int DragStartX;
        private int DragStartY;
        bool scrollingDrag = false;
        public float zoom = 1;
        private bool drag = false;
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right || e.Button == MouseButtons.Left && Control.ModifierKeys == Keys.Alt)
            {
                DragStartX = e.X;
                DragStartY = e.Y;
                scrollingDrag = true;
                return;
            }
            if (e.Button == MouseButtons.Left)
            {
                //if(e.X /
                drag = true;
                this.Focus();
            }

            // if (mode != null)
            //    mode.MouseDown((int)(e.X / zoom) + hScrollBar.Value * 16, (int)(e.Y / zoom) + vScrollBar.Value * 16);

        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (this.PointerClicked != null)
                    this.PointerClicked(this, new EventArgs());
            }
            else if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                float AddX = -(8192f / ((float)scale / 2f) / 10f * hScrollBar1.Value);
                float AddY = -(8192f / ((float)scale / 2f) / 10f * vScrollBar1.Value);
                ContextMenuStrip m = new ContextMenuStrip();
                s = "";
                string thing = "";
                int nr = -1;
                /*for (int i = 0; i < Planes.Length; i++)
                {
                    r = new Rectangle((int)Planes[i].GetMinX(scaleX, pictureBox1.Width) + (int)AddX, (int)Planes[i].GetMinY(scaleY, pictureBox1.Height) + (int)AddY, (int)Planes[i].GetMaxX(scaleX, pictureBox1.Width) - (int)Planes[i].GetMinX(scaleX, pictureBox1.Width), (int)Planes[i].GetMaxY(scaleY, pictureBox1.Height) - (int)Planes[i].GetMinY(scaleY, pictureBox1.Height));
                    if (r.Contains(e.X, e.Y))
                    {
                        s = string.Format("Plane #{0}:\nX: {1}; Z: {2}", i + 1, Planes[i].X, Planes[i].Z);
                        thing = "Plane";
                        nr = i;
                        //MessageBox.Show(s);
                    }
                }*/
                for (int i = 0; i < Vertex.Length; i++)
                {
                    r = new Rectangle((int)Vertex[i].GetMinX(scaleX, pictureBox1.Width) + (int)AddX, (int)Vertex[i].GetMinY(scaleY, pictureBox1.Height) + (int)AddY, (int)Vertex[i].GetMaxX(scaleX, pictureBox1.Width) - (int)Vertex[i].GetMinX(scaleX, pictureBox1.Width), (int)Vertex[i].GetMaxY(scaleY, pictureBox1.Height) - (int)Vertex[i].GetMinY(scaleY, pictureBox1.Height));
                    if (r.Contains(e.X, e.Y))
                    {
                        s = string.Format("Vertex #{0}:\nX: {1}; Z: {2}", i, Vertex[i].X, Vertex[i].Z);
                        thing = "Vertex";
                        nr = i;
                        //MessageBox.Show(s);
                    }
                }
                for (int i = 0; i < Octree.Length; i++)
                {
                    r = new Rectangle((int)Octree[i].GetMinX(scaleX, pictureBox1.Width) + (int)AddX, (int)Octree[i].GetMinY(scaleY, pictureBox1.Height) + (int)AddY, (int)Octree[i].GetMaxX(scaleX, pictureBox1.Width) - (int)Octree[i].GetMinX(scaleX, pictureBox1.Width), (int)Octree[i].GetMaxY(scaleY, pictureBox1.Height) - (int)Octree[i].GetMinY(scaleY, pictureBox1.Height));
                    if (r.Contains(e.X, e.Y))
                    {
                        s = string.Format("Octree #{0}:\nX: {1}; Z: {2}", i + 1, Octree[i].X, Octree[i].Z);
                        thing = "Octree";
                        nr = i;
                        //MessageBox.Show(s);
                    }
                }
                if (s != "")
                {
                    m.Items.Add(new ToolStripButton() { Text = s, Font = new Font(Font, FontStyle.Bold), Enabled = false, ForeColor = Color.Black, DisplayStyle = ToolStripItemDisplayStyle.Text });
                    m.Items.Add(new ToolStripSeparator());
                    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(nkm));
                    m.Items.Add(new ToolStripButton() { Text = "Edit", Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image"))), DisplayStyle = ToolStripItemDisplayStyle.ImageAndText });
                    m.Items[2].Click += new EventHandler(NkmEditorControl_Click);
                    m.Tag = new object[] { thing, nr };
                    m.Show(this, e.Location);
                }
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            pictureBox1.Invalidate();
        }

        void NkmEditorControl_Click(object sender, EventArgs e)
        {
            ToolStripButton m = (ToolStripButton)sender;
            object[] o = (object[])m.Owner.Tag;
            string thing = (string)o[0];
            int nr = (int)o[1];
        }
        public event EventHandler PointerLocationChanged;
        public event EventHandler PointerClicked;

        public float locationX = 0;
        public float locationY = 0;
        ToolTip t = new ToolTip();
        string tip = "";
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            float AddX = -(8192f / ((float)scale / 2f) / 10f * hScrollBar1.Value);
            float AddY = -(8192f / ((float)scale / 2f) / 10f * vScrollBar1.Value);
            locationX = (e.X / scaleX) - (MaxWidth / 2f) + (AddX / 2f);
            locationY = (e.Y / scaleY) - (MaxHeight / 2f) + (AddY / 2f);
            if (this.PointerLocationChanged != null)
                this.PointerLocationChanged(this, new EventArgs());
            /*int DragSpeed = (int)Math.Ceiling(16 * zoom);

            int xx = (int)(e.X / zoom);// + hScrollBar.Value * 16;
            int yy = (int)(e.Y / zoom);// + vScrollBar.Value * 16;

            if (scrollingDrag)
            {
                int NewX = e.X;
                int NewY = e.Y;
                int XDelta = (NewX - DragStartX) / DragSpeed;
                int YDelta = (NewY - DragStartY) / DragSpeed;
                if (XDelta != 0 || YDelta != 0)
                {
                    Point NewPosition = new Point(ViewableArea.X - XDelta, ViewableArea.Y - YDelta);
                    if (NewPosition.X < 0) NewPosition.X = 0;
                    if (NewPosition.X > hScrollBar.Maximum) NewPosition.X = hScrollBar.Maximum;
                    if (NewPosition.Y < 0) NewPosition.Y = 0;
                    if (NewPosition.Y > vScrollBar.Maximum) NewPosition.Y = vScrollBar.Maximum;
                    DragStartX += (XDelta * DragSpeed);
                    DragStartY += (YDelta * DragSpeed);
                    ScrollEditor(NewPosition);
                }
            }
            else if (e.Button == MouseButtons.Left && Ready && mode != null)
                mode.MouseDrag(xx, yy);
            else
                mode.MouseMove(xx, yy);*/
            /*if (drag)
            {

            }
            */
            x = e.X;
            y = e.Y;
            /*s = "";
            for (int i = 0; i < OBJI.Length; i++)
            {
                r = new Rectangle((int)OBJI[i].GetMinX(scaleX, pictureBox1.Width), (int)OBJI[i].GetMinY(scaleY, pictureBox1.Height), (int)OBJI[i].GetMaxX(scaleX, pictureBox1.Width) - (int)OBJI[i].GetMinX(scaleX, pictureBox1.Width), (int)OBJI[i].GetMaxY(scaleY, pictureBox1.Height) - (int)OBJI[i].GetMinY(scaleY, pictureBox1.Height));
                if (r.Contains(x, y))
                {
                    s = string.Format("OBJI #{0}:\nX: {1}\nZ: {2}", i + 1, OBJI[i].X, OBJI[i].Z);
                    //MessageBox.Show(s);
                }
            }
            if(r.Contains(x,y) == false)
            {
                t.Hide(pictureBox1);
            }*/
        }
        int x;
        int y;
        string s;
        private void pictureBox1_SizeChanged(object sender, EventArgs e)
        {
            scaleX = (float)this.Width / MaxWidth;
            scaleY = (float)this.Height / MaxHeight;
            pictureBox1.Invalidate();
        }

        private void NkmEditorControl_Resize(object sender, EventArgs e)
        {
            scaleX = (float)this.Width / MaxWidth;
            scaleY = (float)this.Height / MaxHeight;
            pictureBox1.Invalidate();
        }

        private void NkmEditorControl_MouseMove(object sender, MouseEventArgs e)
        {

        }
        Rectangle r = new Rectangle(0, 0, 0, 0);
        private void pictureBox1_MouseHover(object sender, EventArgs e)
        {
            /* if (s != "")
             {
                 t.Show(s, pictureBox1, x,y);
             }
             else
             {
                 t.Hide(pictureBox1);
             }*/
        }

        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            pictureBox1.Invalidate();
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            pictureBox1.Invalidate();
        }
    }
}
